using System;
using System.Collections;
using System.Data;

using LocalBoard.Domain;

namespace LocalBoard.Persistence.MockAccessor
{
	/// <summary>
	/// Summary description for MockBoardAccessor.
	/// </summary>
	public class MockBoardAccessor : IBoardAccessor, IMockAccessor
	{
		private int _oId = 0;
		private DataTable _boardTable = new DataTable("Board");
		public static readonly MockBoardAccessor Instance = 
			new MockBoardAccessor();

		private MockBoardAccessor()
		{
			_boardTable.Columns.Add("Id", typeof(int));
			_boardTable.Columns.Add("Name", typeof(string));
			_boardTable.Columns.Add("Manager_Id", typeof(int));
			_boardTable.Columns.Add("AccessRole_Id", typeof(int));
			_boardTable.Columns.Add("PostRole_Id", typeof(int));
			_boardTable.Columns.Add("Club_Id", typeof(int));
			_boardTable.Columns.Add("ViewType", typeof(int));
		}

		#region IMockAccessor Members
		public void ResetDataTable()
		{
			_oId = 0;
			_boardTable.Clear();
		}

		public void RemoveRows(int tableIndex, DataRow[] rows)
		{
			throw new NotImplementedException();
		}

		public DataRow[] ExecuteFilter(string filterExpression)
		{
			throw new NotImplementedException();
		}
		#endregion

		#region IBoardAccessor Members

		public ArrayList GetBoardListByClubId(int clubId)
		{
			ArrayList boardList = new ArrayList();
			foreach(DataRow row in _boardTable.Select(string.Format("Club_Id={0}", clubId)))
			{
				boardList.Add(GetBoardFromResultRow(row));
			}
			return boardList;
		}

		public Board Get(int id)
		{
			DataRow[] result = _boardTable.Select(string.Format("Id={0}", id));
			if(result.Length > 0)
				return GetBoardFromResultRow(result[0]);
			else
				return null;
		}
	
		public int Insert(Board board)
		{
			_oId++;
			DataRow newRow = _boardTable.NewRow();
			newRow["Id"] = _oId;
			newRow["Name"] = board.Name;
			if(board.Manager != null)
				newRow["Manager_Id"] = board.Manager.Id;
			else
				newRow["Manager_Id"] = DBNull.Value;
			newRow["AccessRole_Id"] = board.AccessRoleId;
			newRow["PostRole_Id"] = board.PostRoleId;
			newRow["Club_Id"] = board.ClubId;
			newRow["ViewType"] = Board.GetBoardViewTypeId(board.ViewType);
			_boardTable.Rows.Add(newRow);

			return _oId;
		}

		public void Update(Board board)
		{
			DataRow row = FindBoardDataRow(board.Id);
			if(row!=null)
			{
				row["Name"] = board.Name;
				if(board.Manager != null)
					row["Manager_Id"] = board.Manager.Id;
				else
					row["Manager_Id"] = DBNull.Value;
				row["AccessRole_Id"] = board.AccessRoleId;
				row["PostRole_Id"] = board.PostRoleId;
				row["ViewType"] = Board.GetBoardViewTypeId(board.ViewType);
				_boardTable.AcceptChanges();
			}
		}
		
		public void Delete(int id)
		{
			DataRow row = FindBoardDataRow(id);
			if(row!=null)
			{
				_boardTable.Rows.Remove(row);
				_boardTable.AcceptChanges();
			}
		}

		public void AssignManagerToBoard(int profileId, int id)
		{
			DataRow boardRow = FindBoardDataRow(id);
			if(boardRow!=null)
			{
				int clubId = int.Parse(boardRow["Club_Id"].ToString());
				if(!MockClubProfileAccessor.Instance.IsUserInTheClub(profileId, clubId))
					throw new Exception(string.Format("User id, {0} is not a member of the club id, {1}", profileId, clubId));
				boardRow["Manager_Id"] = profileId;
				_boardTable.AcceptChanges();
			}
		}
		#endregion

		private DataRow FindBoardDataRow(int id)
		{
			foreach(DataRow row in _boardTable.Rows)
			{
				if(DataConverter.GetInteger(row["Id"])==id)
					return row;
			}
			return null;
		}

		private Board GetBoardFromResultRow(DataRow row)
		{
			return new Board(DataConverter.GetInteger(row["Id"]), DataConverter.GetString(row["Name"]), MockProfileAccessor.Instance.Get(DataConverter.GetInteger(row["Manager_Id"])), DataConverter.GetInteger(row["AccessRole_Id"]), DataConverter.GetInteger(row["PostRole_Id"]), DataConverter.GetInteger(row["Club_Id"]), Board.GetBoardViewType(DataConverter.GetInteger(row["ViewType"])));
		}
	}
}
